package bold.deposit.useful;

import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Log4j2
@Repository("redis")
public class Redis {
    @Autowired
    private JedisPool jedisPool;

    /**
     * 有效 返回 true
     * -2 不存在
     * -1 永久有效
     */
    public boolean ttl(final String key) {
        Jedis jedis = jedisPool.getResource();
        Long time = jedis.ttl(key);
        close(jedis);
        return !time.equals(-2L);
    }

    public boolean set(String key, String value) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.set(key, value);
        close(jedis);
        return "OK".equals(result);
    }

    public boolean set(String key, String value, int time, TimeUnit unit) {
        return set(key, value, (int) unit.toSeconds(time));
    }

    public boolean set(String key, String value, int seconds) {
        Jedis jedis = jedisPool.getResource();
        String x = jedis.set(key, value);
        Long y = jedis.expire(key, seconds);
        close(jedis);
        return "OK".equals(x) && y > 0L;
    }

    public String get(String key) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.get(key);
        close(jedis);
        return result;
    }

    public String get(String key, String defaultValue) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.get(key);
        close(jedis);
        return result == null ? defaultValue : result;
    }

    public boolean hmset(String key, Map<String, String> map) {
        Jedis jedis = jedisPool.getResource();
        String x = jedis.hmset(key, map);
        close(jedis);
        return "OK".equals(x);
    }

    public List<String> hmget(String key, String... fields) {
        Jedis jedis = jedisPool.getResource();
        if (fields.length == 0) throw new NullPointerException("hmget -> fields not null");
        close(jedis);
        return jedis.hmget(key, fields);
    }

    public Map<String, String> hgetAll(String key) {
        Jedis jedis = jedisPool.getResource();
        close(jedis);
        return jedis.hgetAll(key);
    }

    public boolean lpush(String key, String... strings) {
        Jedis jedis = jedisPool.getResource();
        if (strings.length == 0) throw new NullPointerException("rpush -> strings not null");
        Long x = jedis.rpush(key, strings);
        close(jedis);
        return x > 0L;
    }

    public List<String> lrange(String key) {
        Jedis jedis = jedisPool.getResource();
        List<String> list = jedis.lrange(key, 0, -1);
        close(jedis);
        return list;
    }

    /**
     * Set 无序集合
     */
    public boolean sadd(String key, String... members) {
        Jedis jedis = jedisPool.getResource();
        Long x = jedis.sadd(key, members);
        close(jedis);
        return x > 0L;
    }

    public Set<String> smembers(String key) {
        Jedis jedis = jedisPool.getResource();
        Set<String> set = jedis.smembers(key);
        close(jedis);
        return set;
    }

    public boolean delete(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.del(key);
        close(jedis);
        return result > 0L;
    }

    private void close(Jedis jedis) {
        if (jedis != null) jedis.close();
    }


    public static void main(String[] args) {
        init();
    }

    public static void init() {
        JedisPoolConfig config = new JedisPoolConfig();//创建redis连接池
        // 最大分配的对象数  :控制一个pool最多有多少个状态为idle的jedis实例
        config.setMaxTotal(300);
        //控制一个pool可分配多少个jedis实例，通过pool.getResource()来获取
        //如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)
        config.setMaxIdle(100);
        // 当池内没有返回对象时，最大等待时间 : 超时时间
        config.setMaxWaitMillis(100000);
        // 当调用borrow Object方法时，是否进行有效性检查: 在borrow一个jedis实例时，是否提前进行alidate操作；如果为true，则得到的jedis实例均是可用的；
        config.setTestOnBorrow(true);
        // 当调用return Object方法时，是否进行有效性检查 :在还给pool时，是否提前进行validate操作
        config.setTestOnReturn(true);

        Redis redis = new Redis();
         JedisPool pool = new JedisPool(config, "127.0.0.1", 6379, 200000);
        redis.jedisPool = pool;


        String ok = pool.getResource().set("aa", "1234654");
        System.out.println(ok);
        System.out.println(pool.getResource().ttl("aa"));
        System.out.println(pool.getResource().get("aa"));


        Long a = Long.valueOf(2);
        System.out.println(a.equals(Integer.valueOf(2)));
    }
}
